package ru.neoflex.jedit.plugin.ui;

import org.gjt.sp.jedit.View;
import org.gjt.sp.util.Log;
import ru.neoflex.jedit.plugin.core.Completion;

import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

public class CompletionPopup extends org.gjt.sp.jedit.gui.CompletionPopup implements ICompletionPopup {
    public CompletionPopup(View view, Point location) {
        super(view, location);
        this.view = view;
    }

    public boolean showCompletions(Completion[] completions) {
        if (completions.length == 0) {
            dispose();
            return false;
        } else {
            reset(new CandidatesImpl(completions), true);
            return true;
        }
    }

    public void setWord(String word) {
        this.word = word;
    }

    private View view;
    private String word;

    @Override
    public void keyPressed(KeyEvent evt) {
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            doSelectedCompletion();
            evt.consume();
        } else if (evt.getKeyCode() == KeyEvent.VK_ESCAPE) {
            dispose();
            evt.consume();
        } else if (evt.getKeyCode() == KeyEvent.VK_UP) {
            moveSelection(evt, UP);
            evt.consume();
        } else if (evt.getKeyCode() == KeyEvent.VK_DOWN) {
            moveSelection(evt, DOWN);
            evt.consume();
        } else if (evt.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
            view.getTextArea().backspace();
            evt.consume();
        }
    }

    final protected int DOWN = 0;
    final protected int UP = 1;

    protected void moveSelection(KeyEvent evt, int direction) {
        int selected = getSelectedIndex();

        selected += (direction == DOWN) ? +1 : -1;

        // Wrap around when end/beginning reached
        if (selected == -1) {
            selected = getCandidates().getSize() - 1;
        } else if (selected == (getCandidates().getSize())) {
            selected = 0;
        }

        setSelectedIndex(selected);

        evt.consume();
    }

    @Override
    public void keyTyped(KeyEvent evt) {
    }

    private class CandidatesImpl implements Candidates {
        private final DefaultListCellRenderer renderer = new DefaultListCellRenderer();
        private final Completion[] completions;

        public CandidatesImpl(Completion[] completions) {
            this.completions = completions;
        }

        public int getSize() {
            return completions.length;
        }

        public boolean isValid() {
            return true;
        }

        public void complete(int index) {
            String insertion = completions[index].toString().substring(word.length());
            view.getTextArea().setSelectedText(insertion);
        }

        public Component getCellRenderer(JList list, int index, boolean isSelected, boolean cellHasFocus) {
            renderer.getListCellRendererComponent(list, null, index, isSelected, cellHasFocus);

            Completion comp = completions[index];
            String text = comp.getWord();

            renderer.setText(text);
            return renderer;
        }

        public String getDescription(int index) {
            return "Description goes here";
        }
    }
}